/**
 *
 */
package jp.seraph.jsade.perceptor;

import java.util.HashMap;
import java.util.Map;

import jp.seraph.jsade.sexpression.Node;
import jp.seraph.jsade.sexpression.SExpression;

/**
 *
 *
 */
public class SeeBuilder implements PerceptorBuilder {

    public Perceptor build(Node aNode) {
        int tCount = aNode.childCount() - 1;
        SeeObject[] tObjects = new SeeObject[tCount];

        for (int i = 0; i < tCount; i++) {
            try {
                tObjects[i] = this.buildSeeObject(aNode.getChildAsNode(i + 1));
            } catch (Exception e) {
                System.out.println("SeeObjectのParseに失敗しました");
                e.printStackTrace();
                tObjects[i] = null;
            }
        }

        return new SeePerceptor(tObjects);
    }

    private SeeObject buildSeeObject(Node aNode) {
        if(aNode.childCount() == 2 && aNode.getLeftString().equals("id")){
            System.out.println("See Node has Only 2 Nodes. I insert \"P\" at 0");
            aNode.insertChild("P", 0);
        }

        SeeObjectType tType = SeeObjectType.getObjectType(aNode.getLeftString());

        if (tType == SeeObjectType.PLAYER)
            return buildPlayerSeeObject(aNode);
        else
            return buildSeeObject(aNode, tType);
    }

    private SeeObject buildPlayerSeeObject(Node aNode) {
        String tTeam = aNode.getValue("team");
        String tIdStr = aNode.getValue("id");

        if (tTeam == null || tIdStr == null)
            throw new IllegalArgumentException("ノードの構造が想定のものと違います。");

        Map<String, SeePartObject> tParts = new HashMap<String, SeePartObject>();

        for (SExpression tExpression : aNode) {
            if(tExpression.isLeaf())
                continue;
            if("team".equals(tExpression.getLeftString()))
                continue;
            if("id".equals(tExpression.getLeftString()))
                continue;

            SeePartObject tPart = buildSeePartObject((Node)tExpression);
            tParts.put(tPart.getName(), tPart);
        }

        return new SeeObject(SeeObjectType.PLAYER, SeeObjectConfidence.Actual, tTeam, Integer.parseInt(tIdStr), tParts);
    }

    private SeePartObject buildSeePartObject(Node aNode){
        String[] tPolValues = aNode.getValues("pol");
        String tPartName = aNode.getLeftString();

        double tDistance = Double.parseDouble(tPolValues[0]);
        double tHorizontalAngle = Double.parseDouble(tPolValues[1]);
        double tLatitudalAngle = Double.parseDouble(tPolValues[2]);

        return new SeePartObject(tPartName, tDistance, tHorizontalAngle, tLatitudalAngle);
    }

    private SeeObject buildSeeObject(Node aNode, SeeObjectType aType) {
        String[] tValues = aNode.getValues("pol");

        if (tValues.length != 3)
            throw new IllegalArgumentException("ノードの構造が想定のものと違います。");

        double tDistance = Double.parseDouble(tValues[0]);
        double tHorizontalAngle = Double.parseDouble(tValues[1]);
        double tLatitudalAngle = Double.parseDouble(tValues[2]);

        return new SeeObject(aType, SeeObjectConfidence.Actual, tDistance, tHorizontalAngle, tLatitudalAngle);
    }
}
